#include "io.h"

//#define IO_DEBUG_IN
//#define IO_DEBUG_B

struct extendedMatrix *readMatrix(char *file){

    struct extendedMatrix *M;
    FILE *fp=stdin;
    int error;
    double rop;
    unsigned long i, j, N;

    fp = fopen(file, "r");

    M=(struct extendedMatrix*) calloc(1, sizeof(struct extendedMatrix));

    // read the order of the matrix (J_ORDER)
    error = fscanf(fp, "%lu", &j);
    M->J_ORDER = j; N=j;
    // read the row which will the tested (J_ROW_TEST)
    error = fscanf(fp, "%lu", &j);
    M->J_ROW_TEST=j;
    // read the tolerance (J_ERROR);
    error = fscanf(fp, "%lf", &rop);
    M->J_ERROR = rop;
    // read the max number of interations (J_ITE_MAX)
    error = fscanf(fp, "%lu", &j);
    M->J_ITE_MAX=j;

    #ifdef IO_DEBUG_IN
        printf("N=%lu R=%lu T=%lf I=%lu\n",
        M->J_ORDER,
        M->J_ROW_TEST,
        M->J_ERROR,
        M->J_ITE_MAX
        );
    #endif

    // Allocate the matrix A
    M->matrix = (double **) calloc(N, sizeof(double*));
        for(i=0; i<N; i++)
            M->matrix[i] = (double *) calloc(N, sizeof(double));

    // Allocate the vector B
    M->vector = (double *) calloc(N, sizeof(double));

    // read A
    for(i=0; i<N; i++){
        for(j=0; j<N; j++){
            error = fscanf(fp, "%lf", &rop);
            M->matrix[i][j]=rop;
        }
    }
    
    // read B
    for(j=0; j<N; j++){ 
        error = fscanf(fp, "%lf", &rop);
        M->vector[j]=rop;
        #ifdef IO_DEBUG_B
            printf("vector[%d]=%lf\n", i, M->vector[j]);
        #endif
    }

    fclose(fp);

    return M;
}

int freeMatrix(struct extendedMatrix *M){
    unsigned long i, N;
    N = M->J_ORDER;
    
    for(i=0; i<N; i++)
        free(M->matrix[i]);
    free(M->vector);
    free(M->matrix);
    free(M);
}

int printMatrix(struct extendedMatrix *M){
    unsigned long i, j, N;
    N = M->J_ORDER;

    for(i=0; i<N; i++){
        for(j=0; j<N; j++){
            printf("%.1lf ", M->matrix[i][j]);
        }
        printf("%.1lf\n", M->vector[i]);
    }
}
